package com.xinan.system.generat;


import com.jfinal.kit.StringKit;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

/**
 * 用于生成代码的Table对象.对应数据库的table
 * @author badqiu
 * @email badqiu(a)gmail.com
 */
public class Table implements java.io.Serializable,Cloneable {

    String sqlName;
    String remarks;
    String className;
    String classNameLower;

    LinkedHashSet<Column> columns = new LinkedHashSet<Column>();
    List<Column> primaryKeyColumns = new ArrayList<Column>();


    public Table() {}

    public Table(Table t) {
        setSqlName(t.getSqlName());
        this.remarks = t.getRemarks();
        this.className = t.getClassName();
        this.classNameLower = t.getClassNameFirstLower();
        this.columns = t.getColumns();
        this.primaryKeyColumns = t.getPkColumns();
    }

    public LinkedHashSet<Column> getColumns() {
        return columns;
    }

    /** 数据库中表的表名称,其它属性很多都是根据此属性派生 */
    public String getSqlName() {
        return sqlName;
    }
    public void setSqlName(String sqlName) {
        this.sqlName = sqlName;
    }

    /** 数据库中表的表备注 */
    public String getRemarks() {
        return remarks;
    }
    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }
    public void addColumn(Column column) {
        columns.add(column);
    }

    /**
     * 根据sqlName得到的类名称，示例值: UserInfo
     * @return
     */
    public String getClassName() {
        if(StringKit.isBlank(className)) {
            return StringKit.makeAllWordFirstLetterUpperCase(StringKit.toUnderscoreName(sqlName));
        }else {
            return className;
        }
    }

    /**
     * 根据sqlName得到的类名称，示例值: UserInfo
     * @return
     */
    public String getClassNameLower() {
        if(StringKit.isBlank(classNameLower)) {
            return StringKit.firstCharToLowerCase(getClassName());
        }else {
            return classNameLower;
        }
    }

    /**
     * 等价于getClassName().toLowerCase()
     * @return
     */
    public String getClassNameLowerCase() {
        return getClassName().toLowerCase();
    }
    /**
     * 得到用下划线分隔的类名称，如className=UserInfo,则underscoreName=user_info
     * @return
     */
    public String getUnderscoreName() {
        return StringKit.toUnderscoreName(getClassName()).toLowerCase();
    }
    /**
     * 返回值为getClassName()的第一个字母小写,如className=UserInfo,则ClassNameFirstLower=userInfo
     * @return
     */
    public String getClassNameFirstLower() {
        return StringKit.firstCharToLowerCase(getClassName());
    }

    /**
     * 根据getClassName()计算而来,用于得到常量名,如className=UserInfo,则constantName=USER_INFO
     * @return
     */
    public String getConstantName() {
        return StringKit.toUnderscoreName(getClassName()).toUpperCase();
    }

    /**
     * 得到主键总数
     * @return
     */
    public int getPkCount() {
        int pkCount = 0;
        for(Column c : columns){
            if(c.isPk()) {
                pkCount ++;
            }
        }
        return pkCount;
    }
    /**
     * use getPkColumns()
     * @deprecated
     */
    public List getCompositeIdColumns() {
        return getPkColumns();
    }

    /**
     * 得到是主键的全部column
     * @return
     */
    public List<Column> getPkColumns() {
        List results = new ArrayList();
        for(Column c : getColumns()) {
            if(c.isPk())
                results.add(c);
        }
        return results;
    }

    public void setPkColumns(List<Column> primaryKeyColumns) {
        this.primaryKeyColumns = primaryKeyColumns;
    }

    /**
     * 得到不是主键的全部column
     * @return
     */
    public List<Column> getNotPkColumns() {
        List results = new ArrayList();
        for(Column c : getColumns()) {
            if(!c.isPk())
                results.add(c);
        }
        return results;
    }


    public Column getColumnByName(String name) {
        Column c = getColumnBySqlName(name);
        if(c == null) {
            c = getColumnBySqlName(StringKit.toUnderscoreName(name));
        }
        return c;
    }

    public Column getColumnBySqlName(String sqlName) {
        for(Column c : getColumns()) {
            if(c.getSqlName().equalsIgnoreCase(sqlName)) {
                return c;
            }
        }
        return null;
    }

    public Column getRequiredColumnBySqlName(String sqlName) {
        if(getColumnBySqlName(sqlName) == null) {
            throw new IllegalArgumentException("not found column with sqlName:"+sqlName+" on table:"+getSqlName());
        }
        return getColumnBySqlName(sqlName);
    }

    /**
     * 忽略过滤掉某些关键字的列,关键字不区分大小写,以逗号分隔
     * @param ignoreKeywords
     * @return
     */
    public List<Column> getIgnoreKeywordsColumns(String ignoreKeywords) {
        List results = new ArrayList();
        for(Column c : getColumns()) {
            String sqlname = c.getSqlName().toLowerCase();
            if(StringKit.contains(sqlname,ignoreKeywords.split(","))) {
                continue;
            }
            results.add(c);
        }
        return results;
    }

    public String toString() {
        return "Database Table:"+getSqlName()+" to ClassName:"+getClassName();
    }

    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            //ignore
            return null;
        }
    }
}
